package com.study.rpc;

import com.study.rpc.entity.Request;
import com.study.rpc.entity.Response;

import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

/**
 * @version V1.0
 * @title: ServerService
 * @description: ${DESCRIPTION}
 * @author: wanghuilong
 * @date: 2019-11-11 15:20
 * @copyright: http://fingo.com.my/
 */
public class ServerService implements Runnable {

    private Socket socketClient;

    private Map<String, Class> serviceRegistry = new HashMap<String, Class>();

    private Response response = new Response();


    public ServerService(Socket socketClient) {
        super();
        this.socketClient = socketClient;
    }

    @Override
    public void run() {
        try {
            OutputStream out = socketClient.getOutputStream();
            //建立好连接后，从socket中获取输入流，并建立缓冲区进行读取
            InputStream in = socketClient.getInputStream();
            ObjectInputStream objIn = new ObjectInputStream(in);
            ObjectOutputStream objOut = new ObjectOutputStream(out);

            //获取请求数据，强转参数类型
            Object param = objIn.readObject();
            Request request = null;
            if (!(param instanceof Request)) {
                response.setSuccess(false);
                response.setMessage("参数错误");
                objOut.writeObject(response);
                objOut.flush();
                return;
            } else {
                request = (Request) param;
            }
            //查找并执行服务方法
            System.out.println("要执行的类型为：" + request.getClassName());
            Class service = serviceRegistry.get(request.getClassName());
            if (null != service) {
                Method method = service.getMethod(request.getMethodName(), request.getParamTypes());
                Object result = method.invoke(service.newInstance(), request.getParams());
                //得到结果并返回
                response.setData(result);
            }
            objOut.writeObject(response);
            objOut.flush();
            out.close();
            in.close();
            socketClient.close();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    public void registerService(Class iface, Class imp) {
        this.serviceRegistry.put(iface.getName(), imp);
    }
}
